package com.huishu.tcm.controller;

import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huishu.tcm.entity.*;
import com.huishu.tcm.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "个性化健康管理方案")
@RestController
@RequestMapping("/prescription")
@RequiredArgsConstructor
public class PrescriptionController {

    private final PrescriptionHealthEducationService prescriptionHealthEducationService;
    private final PrescriptionDietService prescriptionDietService;
    private final PrescriptionMotionService prescriptionMotionService;
    private final PrescriptionLoseWeightService prescriptionLoseWeightService;
    private final PrescriptionSleepService prescriptionSleepService;
    private final PrescriptionPhysiqueService prescriptionPhysiqueService;
    private final PrescriptionOtherService prescriptionOtherService;
    private final UserService userService;
    private final HttpServletResponse response;

    @ApiOperation(value = "根据社区id导出患者的个性化健康管理方案", notes = "根据社区id导出患者的个性化健康管理方案")
    @GetMapping(value = "/exportPrescription", params = {"institutionId"})
    public void exportPrescription(int institutionId) throws IOException, IllegalAccessException, NoSuchFieldException {
        // 查询管理组用户数据
        LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(User::getRole, "patient");
        userQueryWrapper.eq(User::getInstitutionId, institutionId);
        List<User> patientList = userService.list(userQueryWrapper);
        List<Integer> patientIdList = patientList.stream().map(User::getId).collect(Collectors.toList());
        SXSSFWorkbook workbook = new SXSSFWorkbook(100);
        String[] userTitleName = {"用户id","姓名", "手机号","性别","年龄","身份证号","是否已结束管理","基层医疗机构id","添加时间","添加用户","更新时间","更新用户"};
        String[] userTitleKey = {"id","name","telNum","gender","age","idNum","endManagement","institutionId","createTime","createUser","updateTime","updateUser"};
        exportUserExcelMethod(workbook,"管理组用户数据",userTitleName,userTitleKey,patientList);

        //查询健康教育处方
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("patient_id", patientIdList);
        List<PrescriptionHealthEducation> healthEducationList = prescriptionHealthEducationService.list(queryWrapper);
        String[] healthEducationName = {"姓名","id", "患者id","传授改善生活方式对改善糖尿病前期有积极意义","学习血糖自我监测方法","学习1-2项中医防病技巧","处方详细内容",
            "其他","其他录入内容","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] healthEducationKey = {"id", "patientId","a1","a2","a3","a4","a5","a6","number","createTime","createUser",
            "updateTime","updateUser","isBlank"};
        exportPrescriptionMethod(workbook, "健康教育处方",healthEducationName, healthEducationKey,patientList,healthEducationList);

        // 查询膳食处方
        List<PrescriptionDiet> dietList = prescriptionDietService.list(queryWrapper);
        String[] dietName = {"姓名","id", "患者id","教授合理饮食、均衡膳食方法","按照“手掌”法则控制膳食","500111法则","中药食药处方","中药食药处方-录入内容","其他","其他录入内容","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] dietKey = {"id", "patientId","a1","a2","a3","a41","a42","a51","a52","number","createTime","createUser","updateTime","updateUser","isBlank"};
        exportPrescriptionMethod(workbook, "膳食处方",dietName, dietKey,patientList,dietList);

        // 查询运动处方
        List<PrescriptionMotion> motionList = prescriptionMotionService.list(queryWrapper);
        String[] motionName = {"姓名","id", "患者id","有氧运动","有氧运动-快走","有氧运动-慢跑","有氧运动-骑自行车","有氧运动-游泳","有氧运动-健身操",
            "有氧运动-乒乓球","有氧运动-羽毛球","有氧运动-其他","有氧运动-其他-录入内容","阻抗运动","阻抗运动-哑铃","阻抗运动-杠铃","阻抗运动-其他","阻抗运动-其他-录入内容",
            "中医传统运动","中医传统运动-24式简化太极拳","中医传统运动-八段锦","中医传统运动-五禽戏","中医传统运动-身心桩","中医传统运动-其他", "中医传统运动-其他-录入内容",
            "运动频次","每次运动时长","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] motionKey = {"id", "patientId","a1","a11","a12","a13","a14","a15","a16","a17","a18","a181",
            "a2","a21","a22","a23","a231","a3","a31","a32","a33","a34","a35","a351","a41","a42","number",
            "createTime","createUser","updateTime","updateUser", "isBlank"};
        exportPrescriptionMethod(workbook, "运动处方",motionName, motionKey,patientList,motionList);

        // 查询减重处方
        List<PrescriptionLoseWeight> loseWeightList = prescriptionLoseWeightService.list(queryWrapper);
        String[] loseWeightName = {"姓名","id", "患者id","控制饮食","增强运动","其他","其他录入内容","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] loseWeightKey = {"id", "patientId","a1","a2","a31","a32","number","createTime","createUser","updateTime","updateUser","isBlank"};
        exportPrescriptionMethod(workbook, "减重处方",loseWeightName, loseWeightKey,patientList,loseWeightList);

        // 查询睡眠处方
        List<PrescriptionSleep> sleepList = prescriptionSleepService.list(queryWrapper);
        String[] sleepName = {"姓名","id", "患者id","每天保持6-8小时睡眠","其他","其他录入内容","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] sleepKey = {"id", "patientId","a1","a2","a21","number","createTime","createUser","updateTime","updateUser","isBlank"};
        exportPrescriptionMethod(workbook, "睡眠处方",sleepName, sleepKey, patientList, sleepList);

        // 查询体质改善处方
        List<PrescriptionPhysique> physiqueList = prescriptionPhysiqueService.list(queryWrapper);
        String[] physiqueName = {"姓名","id", "患者id","湿热蕴脾证","湿热蕴脾证-半夏泻心汤加减","湿热蕴脾证-其他","湿热蕴脾证-其他-录入内容","脾虚湿困证",
            "脾虚湿困证-六君子汤加减","脾虚湿困证-其他","脾虚湿困证-其他-录入内容","肝郁气滞证","肝郁气滞证-四逆散加减","肝郁气滞证-其他","肝郁气滞证-其他-录入内容",
            "其他","其他录入内容","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] physiqueKey = {"id", "patientId","a1","a11","a12","a13","a2","a21","a22","a23","a3","a31","a32","a33","a4","a41","number","createTime","createUser","updateTime","updateUser","isBlank"};
        exportPrescriptionMethod(workbook, "体质改善处方",physiqueName, physiqueKey, patientList, physiqueList);

        // 查询其他处方
        List<PrescriptionOther> otherList = prescriptionOtherService.list(queryWrapper);
        String[] otherName = {"姓名","id", "患者id","处方内容","第几次录入","添加时间","添加用户","更新时间","更新用户","是否填写该处方"};
        String[] otherKey = {"id", "patientId","content","number","createTime","createUser","updateTime","updateUser","isBlank"};
        exportPrescriptionMethod(workbook, "其他处方",otherName, otherKey, patientList, otherList);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=export.xlsx");
        ServletOutputStream out = response.getOutputStream();
        workbook.write(out);
        workbook.dispose();
        workbook.close();
        out.close();
    }

    // 导出管理组用户数据
    private void exportUserExcelMethod(SXSSFWorkbook workbook, String sheetName, String[] titleName, String[] titleKey, List dataList) throws IllegalAccessException, IOException {
        SXSSFSheet sheet = (SXSSFSheet)workbook.createSheet(sheetName);
        Row row = sheet.createRow(0);
        Cell cell;
        for(int i = 0;i < titleName.length; i++){
            cell = row.createCell(i);
            cell.setCellValue(titleName[i]);
        }
        for(int i = 0;i < dataList.size();i++){
            row = sheet.createRow(i+1);
            Object data = dataList.get(i);
            Field[] sonFields = data.getClass().getDeclaredFields();
            Field[] parentFields = data.getClass().getSuperclass().getDeclaredFields();
            Field[] fields = ArrayUtil.addAll(sonFields,parentFields);
            for(int j = 0;j < titleKey.length;j++){
                cell = row.createCell(j);
                for(Field f: fields){
                    if(f.getName().equals(titleKey[j])){
                        f.setAccessible(true);
                        if("createTime".equals(titleKey[j]) || "updateTime".equals(titleKey[j])){
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            cell.setCellValue(f.get(data) == null?"":sdf.format(f.get(data)));
                        }else{
                            cell.setCellValue(f.get(data) == null?"":f.get(data).toString());
                        }
                        if((i+1)%500==0 && (i+1) > 0){
                            sheet.flushRows();
                        }
                        break;
                    }
                }
            }
        }
    }
    // 导出个性化健康管理方案
    private void exportPrescriptionMethod(SXSSFWorkbook workbook, String sheetName, String[] titleName, String[] titleKey, List<User> patientList, List dataList) throws IllegalAccessException, NoSuchFieldException, IOException {
        SXSSFSheet sheet = (SXSSFSheet)workbook.createSheet(sheetName);
        Row row = sheet.createRow(0);
        Cell cell;
        for(int i = 0;i < titleName.length; i++){
            cell = row.createCell(i);
            cell.setCellValue(titleName[i]);
        }
        int rowCount = 1;
        for(User user: patientList){
            for(int i = 0;i < dataList.size();i++){
                Object data = dataList.get(i);
                Field patientIdField = data.getClass().getDeclaredField("patientId");
                patientIdField.setAccessible(true);
                if(user.getId().equals(patientIdField.get(data))){
                    row = sheet.createRow(rowCount++);
                    cell = row.createCell(0);
                    cell.setCellValue(user.getName());
                    Field[] sonFields = data.getClass().getDeclaredFields();
                    Field[] parentFields = data.getClass().getSuperclass().getDeclaredFields();
                    Field[] fields = ArrayUtil.addAll(sonFields,parentFields);
                    for(int j = 0;j < titleKey.length;j++){
                        cell = row.createCell(j + 1);
                        for(Field f: fields){
                            if(f.getName().equals(titleKey[j])){
                                f.setAccessible(true);
                                if("createTime".equals(titleKey[j]) || "updateTime".equals(titleKey[j])){
                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    cell.setCellValue(f.get(data) == null?"":sdf.format(f.get(data)));
                                }else{
                                    cell.setCellValue(f.get(data) == null?"":f.get(data).toString());
                                }
                                if((rowCount - 1) % 500==0 && rowCount > 0){
                                    sheet.flushRows();
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

}
